package cn.iluwen.airline.Services;

import cn.iluwen.airline.DTOs.user.response.FlightSearchResponse;
import cn.iluwen.airline.Entities.Airport;
import cn.iluwen.airline.Entities.Flight;
import cn.iluwen.airline.Entities.Seat;
import cn.iluwen.airline.Mapper.AirportMapper;
import cn.iluwen.airline.Mapper.FlightMapper;
import cn.iluwen.airline.Mapper.SeatMapper;
import cn.iluwen.airline.utils.PageUtils;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户航班服务类
 * 处理用户航班查询、订票等操作
 */
@Service
public class UserFlightService {
    
    @Autowired
    private FlightMapper flightMapper;
    
    @Autowired
    private AirportMapper airportMapper;
    
    @Autowired
    private SeatMapper seatMapper;
    
    /**
     * 根据出发城市、到达城市和出发日期搜索航班
     * @param departureCity 出发城市
     * @param arrivalCity 到达城市
     * @param departureDate 出发日期
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @return 搜索结果
     */
    public FlightSearchResponse searchFlights(String departureCity, String arrivalCity, 
                                            LocalDate departureDate, Integer pageNum, Integer pageSize) {
        // 根据城市名查找相关机场
        List<Airport> departureAirports = airportMapper.findByCity(departureCity);
        List<Airport> arrivalAirports = airportMapper.findByCity(arrivalCity);
        
        if (departureAirports.isEmpty() || arrivalAirports.isEmpty()) {
            // 如果没有找到对应城市的机场，返回空结果
            FlightSearchResponse response = new FlightSearchResponse();
            response.setTotal(0);
            response.setPages(0);
            response.setPageNum(pageNum != null ? pageNum : 1);
            response.setPageSize(pageSize != null ? pageSize : 0);
            response.setList(new ArrayList<>());
            return response;
        }
        
        // 提取机场ID列表
        List<String> departureAirportIds = departureAirports.stream()
                .map(Airport::getAirportId)
                .collect(Collectors.toList());
        
        List<String> arrivalAirportIds = arrivalAirports.stream()
                .map(Airport::getAirportId)
                .collect(Collectors.toList());
        
        // 设置查询的时间范围为当天的0点到23:59:59
        java.time.LocalDateTime startOfDay = departureDate.atStartOfDay();
        java.time.LocalDateTime endOfDay = departureDate.atTime(LocalTime.MAX);
        
        // 使用分页查询
        PageUtils.startPage(pageNum, pageSize);
        List<Flight> flights = flightMapper.findByCitiesAndDate(
                departureAirportIds, arrivalAirportIds, startOfDay, endOfDay);
        
        // 获取查询结果的分页信息
        PageInfo<Flight> pageInfo = PageUtils.getPageInfo(flights);
        
        // 构建响应对象
        FlightSearchResponse response = new FlightSearchResponse();
        response.setTotal(pageInfo.getTotal());
        response.setPages(pageInfo.getPages());
        response.setPageNum(pageInfo.getPageNum());
        response.setPageSize(pageInfo.getPageSize());
        
        // 创建机场ID到机场信息的映射，减少数据库查询次数
        Map<String, Airport> airportMap = new HashMap<>();
        List<Airport> allRelatedAirports = new ArrayList<>();
        allRelatedAirports.addAll(departureAirports);
        allRelatedAirports.addAll(arrivalAirports);
        
        for (Airport airport : allRelatedAirports) {
            airportMap.put(airport.getAirportId(), airport);
        }
        
        // 获取每个航班的可用座位数量
        Map<String, Integer> availableEconomySeatsMap = new HashMap<>();
        Map<String, Integer> availableBusinessSeatsMap = new HashMap<>();
        
        for (Flight flight : flights) {
            List<Seat> availableSeats = seatMapper.findAvailableSeatsByFlightId(flight.getFlightId());
            
            // 统计经济舱和商务舱的可用座位数
            int economySeats = 0;
            int businessSeats = 0;
            
            for (Seat seat : availableSeats) {
                if ("economy".equals(seat.getSeatClass())) {
                    economySeats++;
                } else if ("business".equals(seat.getSeatClass())) {
                    businessSeats++;
                }
            }
            
            availableEconomySeatsMap.put(flight.getFlightId(), economySeats);
            availableBusinessSeatsMap.put(flight.getFlightId(), businessSeats);
        }
        
        // 转换数据模型
        List<FlightSearchResponse.FlightItem> flightItems = flights.stream().map(flight -> {
            FlightSearchResponse.FlightItem item = new FlightSearchResponse.FlightItem();
            item.setFlightId(flight.getFlightId());
            item.setFlightNumber(flight.getFlightNumber());
            
            // 设置出发机场信息
            Airport departureAirport = airportMap.get(flight.getDepartureAirportId());
            if (departureAirport != null) {
                item.setDepartureAirportCode(departureAirport.getAirportCode());
                item.setDepartureAirportName(departureAirport.getAirportName());
                item.setDepartureCity(departureAirport.getCity());
            }
            
            // 设置到达机场信息
            Airport arrivalAirport = airportMap.get(flight.getArrivalAirportId());
            if (arrivalAirport != null) {
                item.setArrivalAirportCode(arrivalAirport.getAirportCode());
                item.setArrivalAirportName(arrivalAirport.getAirportName());
                item.setArrivalCity(arrivalAirport.getCity());
            }
            
            item.setDepartureTime(flight.getDepartureTime());
            item.setArrivalTime(flight.getArrivalTime());
            item.setEconomyPrice(flight.getEconomyPrice());
            item.setBusinessPrice(flight.getBusinessPrice());
            
            // 设置可用座位数
            item.setAvailableEconomySeats(availableEconomySeatsMap.getOrDefault(flight.getFlightId(), 0));
            item.setAvailableBusinessSeats(availableBusinessSeatsMap.getOrDefault(flight.getFlightId(), 0));
            
            return item;
        }).collect(Collectors.toList());
        
        response.setList(flightItems);
        return response;
    }
} 